import { Injectable } from '@nestjs/common';
const { MongoClient } = require('mongodb');
const { nanoid } = require('nanoid')
import { createIndex, findIndex, deleteDoc } from '../elastic/elastic'
const Redis = require("ioredis");


const redis_client1 = new Redis({
    port: 6379, // Redis port
    host: "127.0.0.1", // Redis host
    db: 1,
});

@Injectable()
export class GalleryService {
    mongoUrl: any = process.env.mongoUrl;
    db: any;
    constructor() {
        this.connect()
        // run()
    }

    async connect() {
        this.db = await MongoClient.connect(this.mongoUrl, { useUnifiedTopology: true })
    }

    async create(userId, gallery_json) {
        const dbo = this.db.db("forum");
        gallery_json["userId"] = userId.userId.toString()
        gallery_json["username"] = userId.username.toString()
        gallery_json["date"] = new Date()
        let gid = nanoid(12)
        if (gallery_json["gid"] != null) {
            gid = gallery_json["gid"]
        }
        if (gallery_json.token != null && gallery_json.token != "") {
            await redis_client1.hmset(gid.toString(), "token", gallery_json.token, "nice", 0)
        }
        const result = await dbo.collection("gallery").insertOne({ "raw": gallery_json, "tags": gallery_json.tags, "replys": [], "gid": gid, "userId": userId.userId, "last_update": new Date(), "nice": 0 })
        createIndex("gallery", gid, gallery_json)
        if (result.insertedCount) {
            return { "status": 20000, "gid": gid }
        } else {
            return { "status": 40000, "info": JSON.stringify(result) }
        }
    }

    async deleteDoc(post_json) {
        // console.log(post_json)
        const dbo = this.db.db("forum");
        let res = await dbo.collection("gallery").deleteOne({ gid: post_json.gid })
        console.log(res.deletedCount)
        deleteDoc('gallery', post_json.gid)
        return { 'status': 20000 }
    }

    async niceJob(userId: string, gid: string) {
        // console.log(gid)

        let res = await redis_client1.hget(gid, userId)
        // console.log("good", res)

        if (res == "false" || res == false || res == null) {
            await redis_client1.hincrby(gid, "nice", 1)
            await redis_client1.hset(gid, userId, true)
            return { "status": 20000 }
        } else {
            return { "status": 40000, "info": "点这么多次赞有屁用" }
        }
    }

    async badJob(userId: string, gid: string) {
        // console.log(gid)
        let res = await redis_client1.hget(gid, userId)
        // console.log("bad", res)
        if (res == "true" || res == true || res == null) {
            await redis_client1.hincrby(gid, "nice", -1)
            await redis_client1.hset(gid, userId, false)
            return { "status": 20000 }
        } else {
            return { "status": 40000, "info": "黑粉爬" }
        }

    }

    async niceCount(gid: string) {
        let res = await redis_client1.hget(gid, "nice")
        if (res == null) {
            return { "status": 40000, "info": "黑粉爬" }
        }
        return { "status": 20000, "nice": res }
    }

    async addTag(userId, gallery_json) {

        const dbo = this.db.db("forum");
        gallery_json["userId"] = userId.userId.toString()
        // gallery_json["date"] = new Date()
        const result = await dbo.collection("gallery").updateOne({ "gid": gallery_json.gid }, { $addToSet: { "tags": gallery_json.tag } })
        if (result.modifiedCount) {
            return { "status": 20000, "gid": gallery_json.gid }
        } else {
            return { "status": 40000, "info": JSON.stringify(result) }
        }
    }

    async searchTag(gallery_json) {
        const dbo = this.db.db("forum");
        let whereStr = { "tag": { $in: gallery_json.tag } }

        const result = await dbo.collection("gallery").find(whereStr).toArray()
        if (result) {
            return { "status": 20000, "result": result }
        } else {
            return { "status": 40000, "info": JSON.stringify(result) }
        }
    }

    async searchBody(gallery_json) {
        let result = await findIndex("gallery", gallery_json.body)
        if (result.length > 0) {
            return { "status": 20000, "result": result }
        } else if (result.length == 0) {
            return { "status": 20000, "result": [] }
        } else {
            return { "status": 40000, "info": JSON.stringify(result) }
        }
    }

    async setToken(gid, token_json) {
        return await redis_client1.hset(gid.toString(), "token", token_json.token)
    }

    async viewPosts(gid: string, token_json, logined: boolean) {
        if (!logined && token_json != null) {
            let token;
            token = token_json.token
            let res = await redis_client1.hget(gid.toString(), "token")
            if (res != token) {
                return { status: 40000, "info": "wrong token" }
            }
        } else if (!logined && token_json == null) {
            return { "status": 40000, "info": "no token" }
        }

        const dbo = this.db.db("forum");
        const whereStr = {
            "gid": gid.toString()
        }
        const result = await dbo.collection("gallery").findOne(whereStr)
        if (result) {
            return {
                "status": 20000,
                "raw": result.raw,
                "replys": result.replys,
                "data": result.last_update
                // "ticket_status": result.ticket_status
            }
        } else {
            return { "status": 40000, "info": JSON.stringify(result) }
        }
    }

    async count() {
        const dbo = this.db.db("forum");
        const count = await dbo.collection("gallery").countDocuments()
        return Math.ceil(count)
    }

    async page(pagenum: number, user_info) {
        const per_page: number = 6
        const temp_page = Math.floor(+(pagenum))
        if (temp_page <= 0) {
            return { "status": 40000, "gallery": [] }
        }
        if (temp_page > 1 && user_info == null) {
            return { "status": 30000, "gallery": [], "info": "need to login" }
        }
        const dbo = this.db.db("forum");
        const gallery_list = await dbo.collection("gallery").find({}).sort({ last_update: -1 }).skip(per_page * (temp_page - 1)).limit(per_page).toArray()
        return { "status": 20000, "gallery": gallery_list }
    }
}
